package com.hipmarket.platform.security.config

import com.hipmarket.platform.security.JwtAuthenticationFilter
import com.hipmarket.platform.security.JwtAuthenticationProvider
import com.hipmarket.platform.security.service.JwtAuthenticationService
import com.hipmarket.platform.security.service.JwtAuthenticationServiceImpl
import com.hipmarket.platform.security.storage.JwtAuthenticationMemoryStorage
import com.hipmarket.platform.security.storage.JwtAuthenticationStorage
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.http.HttpMessageConverters
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer

@Suppress("SpringJavaInjectionPointsAutowiringInspection")
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "jwt.security", ignoreUnknownFields = true, ignoreInvalidFields = true)
class JwtSecurityConfigration: WebSecurityConfigurerAdapter(), WebMvcConfigurer {

    @Autowired
    private lateinit var jwtAuthenticationStorage: JwtAuthenticationStorage

    @Autowired
    lateinit var messageConverters: HttpMessageConverters

    @Value("\${jwt.security.permit-urls:/auth/**}.split(',')")
    val permitUrls: List<String> = listOf("/auth/**")


    @Bean
    @ConditionalOnMissingBean
    fun jwtAuthenticationStorage(): JwtAuthenticationStorage {
        return JwtAuthenticationMemoryStorage()
    }

    @Bean
    @ConditionalOnMissingBean
    fun jwtAuthenticationService(jwtAuthenticationStorage: JwtAuthenticationStorage): JwtAuthenticationService {
        return JwtAuthenticationServiceImpl(jwtAuthenticationStorage)
    }

    override fun configure(http: HttpSecurity) {
        http.formLogin().disable().httpBasic().disable()
                .cors().and().csrf().disable()
                .sessionManagement().disable()

        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter::class.java)
    }

    override fun configure(auth: AuthenticationManagerBuilder) {
        auth.authenticationProvider(JwtAuthenticationProvider(jwtAuthenticationStorage))
    }

    private fun jwtAuthenticationFilter(): JwtAuthenticationFilter {
        return JwtAuthenticationFilter(this.authenticationManager(), permitUrls)
    }


    override fun addArgumentResolvers(resolvers: MutableList<HandlerMethodArgumentResolver>) {
        resolvers.add(JwtAuthenticationMethodArgumentResolver(messageConverters.converters))
    }





}